package jalus.dao;

import jalus.model.PMF;
import jalus.model.Post;

import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

public class PostDAO {
	@SuppressWarnings("unchecked")
	public List<Post> getAllPost(){
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setOrdering("date desc");
	    query.setFilter("(privilege == 1 || privilege == 0)");
	    List<Post> postList;
	    try{
	    	postList = (List<Post>) query.execute();
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}
	
	@SuppressWarnings("unchecked")
	public List<Post> getRangePost(int startpos, int endpos){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
	    Query query = pm.newQuery(Post.class);
	    query.setOrdering("date desc");
	    query.setFilter("(privilege == 1 || privilege == 0)");
	    query.setRange(startpos, endpos);
	    List<Post> postList;
	    try{
	    	postList = (List<Post>) query.execute();
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}

	@SuppressWarnings("unchecked")
	public List<Post> getRangePostByTag(String tag, int startpos, int endpos) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setFilter("tags == tag && (privilege == 1 || privilege == 0)");
	    query.setOrdering("date desc");
	    query.declareParameters("String tag");
	    
	    query.setRange(startpos, endpos);
	    List<Post> postList;
	    try{
	    	postList = (List<Post>) query.execute(tag);
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}
	
	@SuppressWarnings("unchecked")
	public List<Post> getPostListByDateRange(Date startDate, Date endDate) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setFilter("(privilege == 1 || privilege == 0) && date>startDate && date<endDate");
	    query.setOrdering("date desc");
	    query.declareParameters("java.util.Date startDate, java.util.Date endDate");
	    
	    List<Post> postList;
	    try{
	    	postList = (List<Post>) query.execute(startDate, endDate);
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}
	
	public Post getPostById(Long id){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Post post;
		try{
			post = pm.getObjectById(Post.class, id);
		}finally{
			pm.close();
		}
		return post;
	}
	
	public void updatePost(Post newPost){
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Post post = pm.getObjectById(Post.class, newPost.getId());
		try{
			post.setAuthor(newPost.getAuthor());
			post.setContent(newPost.getContent());
			post.setLast_modify_by(newPost.getLast_modify_by());
			post.setLast_modify_date(newPost.getLast_modify_date());
			post.setPrivilege(newPost.getPrivilege());
			post.setTitle(newPost.getTitle());
			post.setTags(newPost.getTags());
			if(newPost.getDate() != null){
				post.setDate(newPost.getDate());
			}
		}finally{
			pm.close();
		}
	}

	public void deletePostById(Long id) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Post post = pm.getObjectById(Post.class, id);
		try{
			pm.deletePersistent(post);
		}finally{
			pm.close();
		}
	}

	public Long addPost(Post post) {
        PersistenceManager pm = PMF.get().getPersistenceManager();
        Long id = null;
        try {
            id = new Long(pm.makePersistent(post).getId());
        } finally {
            pm.close();
        }
        return id;
		
	}

	@SuppressWarnings("unchecked")
	public List<Post> getSpinPostList() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setOrdering("date desc");
	    query.setFilter("privilege == 2");
	    List<Post> postList;
	    try{
	    	postList = (List<Post>) query.execute();
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}

	/**
	 * 
	 * @param startDate do not use this condition if null 
	 * @param length
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Post> getPostListByDate(Date startDate, int length) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setOrdering("date desc");
	    if(startDate!=null){
	    	query.setFilter("(privilege == 1 || privilege == 0) && date < startDate");
	    	query.declareParameters("java.util.Date startDate");
	    }else{
	    	query.setFilter("(privilege == 1 || privilege == 0)");
	    }
	    query.setRange(0, length);
	    List<Post> postList;
	    try{
	    	if(startDate!=null){
	    		postList = (List<Post>) query.execute(startDate);
	    	}else{
	    		postList = (List<Post>) query.execute();
	    	}
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}

	/**
	 * 
	 * @param tag cannot be null 
	 * @param startDate do not use this condition if null 
	 * @param length
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<Post> getPostListByTagAndDate(String tag, Date startDate, int length) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
	    Query query = pm.newQuery(Post.class);
	    query.setOrdering("date desc");
	    
	    
	    if(startDate != null){
	    	query.setFilter("tags == tag && (privilege == 1 || privilege == 0) && date < startDate");
	    	query.declareParameters("String tag, java.util.Date startDate");
	    }else{
	    	query.setFilter("tags == tag && (privilege == 1 || privilege == 0)");
	    	query.declareParameters("String tag");
	    }
	    
	    query.setRange(0, length);
	    
	    List<Post> postList;
	    try{
	    	if(startDate != null){
	    		postList = (List<Post>) query.execute(tag, startDate);
	    	}else{
	    		postList = (List<Post>) query.execute(tag);
	    	}
	    }finally{
	    	query.closeAll();
	    }
	    return postList;
	}

}
